using System;
using System.Collections.Generic;
using System.Text;

namespace OracleInternal.SqlAndPlsqlParser
{
	[Serializable]
	internal class RuleTuple : RuleTupleBase<string>, IStreamable
	{
		public class RuleTupleHeadComparer : IComparer<RuleTuple>
		{
			public static RuleTupleHeadComparer s_vInstance = new RuleTupleHeadComparer();

			private RuleTupleHeadComparer()
			{
			}

			public int Compare(RuleTuple x, RuleTuple y)
			{
				return string.Compare(x.m_vHead, y.m_vHead);
			}
		}

		static RuleTuple()
		{
			RuleTupleBase<string>.s_vNullHeadHashCode = string.Empty.GetHashCode();
		}

		public RuleTuple(string h, List<string> r)
			: base(h, r)
		{
		}

		public RuleTuple(string h, string[] r)
			: base(h, r)
		{
		}

		public RuleTuple()
		{
		}

		public override int CompareTo(RuleTupleBase<string> src)
		{
			RuleTuple ruleTuple = src as RuleTuple;
			if (ruleTuple == null)
			{
				return 1;
			}
			int num = string.Compare(m_vHead, ruleTuple.m_vHead);
			if (num == 0)
			{
				string[] vRhs = ruleTuple.m_vRhs;
				if (m_vRhs == null)
				{
					if (vRhs != null)
					{
						num = -1;
					}
				}
				else if (vRhs == null)
				{
					num = 1;
				}
				else
				{
					int num2 = m_vRhs.Length;
					num = num2 - vRhs.Length;
					int num3 = 0;
					while (num == 0 && num3 < num2)
					{
						num = string.Compare(m_vRhs[num3], vRhs[num3]);
						num3++;
					}
				}
			}
			return num;
		}

		public bool IgnoreRule(string keyword, string bra, string ket)
		{
			bool flag = false;
			string[] vRhs = m_vRhs;
			foreach (string a in vRhs)
			{
				if (flag)
				{
					if (a == keyword)
					{
						return true;
					}
				}
				else
				{
					flag = a == bra;
				}
				if (a == ket)
				{
					return false;
				}
			}
			return false;
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder(1024);
			if (m_vHead != null)
			{
				stringBuilder.Append(m_vHead);
				stringBuilder.Append(':');
			}
			string[] vRhs = m_vRhs;
			foreach (string value in vRhs)
			{
				stringBuilder.Append(' ');
				stringBuilder.Append(value);
			}
			return stringBuilder.ToString();
		}

		public virtual string ToHTML(RuleTuple predecessor)
		{
			StringBuilder sb = new StringBuilder(256);
			if (predecessor == null || predecessor.m_vHead != m_vHead)
			{
				sb.Append(m_vHead);
				sb.Append(':');
				Service.IndentLine(12 - m_vHead.Length - 2, " ", ref sb);
			}
			else
			{
				Service.IndentLine(10, "| ", ref sb);
			}
			string[] vRhs = m_vRhs;
			foreach (string text in vRhs)
			{
				sb.Append(' ');
				if (text.StartsWith("'"))
				{
					sb.Append('"');
					sb.Append(text.Substring(1, text.Length - 2));
					sb.Append('"');
				}
				else
				{
					sb.Append(text);
				}
			}
			return sb.ToString();
		}

		public virtual int WriteToStream(OutputStream ostrm)
		{
			ostrm.WriteLine(ToString());
			return 0;
		}

		public virtual int ReadFromStream(InputStream istrm)
		{
			return ReadFromString(istrm.ReadLine()!.Trim());
		}

		public virtual int ReadFromString(string str)
		{
			string[] array = str.Split(RuleTupleBase<string>.s_vColonDelimiter, 2);
			m_vHead = array[0];
			if (array.Length > 1)
			{
				m_vRhs = array[1].Split(RuleTupleBase<string>.s_vSpaceDelimiter, StringSplitOptions.RemoveEmptyEntries);
			}
			else
			{
				m_vRhs = RuleTupleBase<string>.s_vEmptyStringArray;
			}
			m_vHashValue = null;
			return 0;
		}

		public static void WriteRules(StreamableSet<RuleTuple> rules, OutputStream ostr)
		{
			ostr.WriteObjectData(rules);
			ostr.Close();
		}

		public static StreamableSet<RuleTuple> ReadRules(InputStream istr)
		{
			StreamableSet<RuleTuple> result = istr.ReadObjectData<StreamableSet<RuleTuple>>();
			istr.Close();
			return result;
		}

		public static void PrintRules(StreamableSet<RuleTuple> rules)
		{
			RuleTuple predecessor = null;
			foreach (RuleTuple rule in rules)
			{
				Console.WriteLine(rule.ToHTML(predecessor));
				predecessor = rule;
			}
		}

		public static Set<RuleTuple> ReadUnifiedRules(InputStream istrm)
		{
			Set<RuleTuple> set = new Set<RuleTuple>();
			while (!istrm.EndOfStream)
			{
				string text = istrm.ReadLine()!.Trim();
				if (!text.StartsWith("#") && text.Length != 0)
				{
					RuleTuple ruleTuple = new RuleTuple();
					ruleTuple.ReadFromString(text);
					set.Add(ruleTuple);
				}
			}
			istrm.Close();
			return set;
		}
	}
}
